package com.wsoft.form.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wsoft.constant.FieldKindConstant;
import com.wsoft.core.exception.Asserts;
import com.wsoft.core.handler.ICodeRuleHandler;
import com.wsoft.core.utils.LoginUserUtil;
import com.wsoft.entity.BaseEntity;
import com.wsoft.form.entity.*;
import com.wsoft.form.enums.FormStatusEnum;
import com.wsoft.form.manager.*;
import com.wsoft.form.query.design.DesignBaseQuery;
import com.wsoft.form.query.design.DesignInsertQuery;
import com.wsoft.form.query.design.DesignListQuery;
import com.wsoft.form.query.design.DesignUpdateQuery;
import com.wsoft.form.service.IWfFormDesignService;
import com.wsoft.vo.LoginUserVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 自定义表单-设计表 服务实现类
 * </p>
 *
 * @author Z001
 * @since 2024年08月29日 09:11:06
 */
@Service
public class WfFormDesignServiceImpl  implements IWfFormDesignService {

    @Resource
    private WfFormDesignManager designManager;
    @Resource
    private WfFormTableManager tableManager;
    @Resource
    private WfFormColumnManager columnManager;
    @Resource
    private WfFormVirtualColumnManager virtualColumnManager;
    @Resource
    private WfFormTableRelationManager relationManager;
    @Resource
    private WfFormColumnLinkManager linkManager;
    @Resource
    private WfFormManager formManager;
    @Resource
    private ICodeRuleHandler codeRuleHandler;
    /**
     * 新增自定义表单
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertFormDesign(DesignInsertQuery query) {
        WfFormDesignEntity entity = Convert.convert(WfFormDesignEntity.class, query);
        //校验 designCode
        checkFormDesignCode(query);
        designManager.save(entity);

        //跟新状态
        WfFormEntity formEntity = formManager.getById(query.getFormId());
        formEntity.setStatus(FormStatusEnum.DESIGN.getValue());
        formManager.updateById(formEntity);

        return true;
    }

    /**
     * 修改自定义表单
     * @param query
     * @return
     */
    @Override
    public boolean updateFormDesign(DesignUpdateQuery query) {
        WfFormDesignEntity entity = Convert.convert(WfFormDesignEntity.class, query);
        //校验 designCode
        checkFormDesignCode(query);
        return designManager.updateById(entity);

    }

    /**
     * 获取自定义表单列表
     * @param id
     */
    @Override
    public  List<WfFormDesignEntity> listFormDesign(DesignListQuery query) {
       return designManager.getByFormId(query);
    }

    /**
     * 删除自定义表单
     * @param designId
     * @return
     */
    @Override
    public boolean delFormDesign(Long designId) {
        return designManager.removeById(designId);
    }

    /**
     * 获取指定在线表单对象在前端渲染时所需的所有数据对象
     * @param designId
     * @return
     */
    @Override
    public JSONObject render(Long designId) {
        JSONObject jsonObject = new JSONObject();
        WfFormDesignEntity designEntity = designManager.getById(designId);
        // 表单
        jsonObject.put("formDesignInfo", designEntity);

        List<Long> tableIdList = new ArrayList<>();

        // 主表信息
        WfFormTableEntity masterTableEntity = tableManager.getById(designEntity.getTableId());
        tableIdList.add(masterTableEntity.getId());
        //关联主表的 其他关联表
        List<WfFormTableRelationEntity> masterRelation = relationManager.getMasterRelation(designEntity.getFormId(), designEntity.getTableId());
        //主表关联信息
        jsonObject.put("relationList", masterRelation);

        //获取其他关联表信息
        for (WfFormTableRelationEntity relation : masterRelation) {
            tableIdList.add(relation.getSlaveTableId());
        }

        //查询表信息
        List<WfFormTableEntity> tableList =  tableManager.listByIds(tableIdList);
        //查询表字段信息
        List<WfFormColumnEntity> columnList = columnManager.getColumnList(tableIdList);
        //查询表字段虚拟信息
        List<WfFormVirtualColumnEntity> virtualColumnList = virtualColumnManager.getByTableId(tableIdList);

        List<Long> columnIdList = columnList.stream().map(BaseEntity::getId).collect(Collectors.toList());
        //查询字段关联表信息
        List<WfFromColumnLinkEntity> linkList = linkManager.getByColumnId(columnIdList);

        //表信息
        jsonObject.put("tableList", tableList);
        //字段信息
        jsonObject.put("columnList", columnList);
        //虚拟字段信息
        jsonObject.put("virtualColumnList", virtualColumnList);
        //字段关联信息
        jsonObject.put("linkList", linkList);

        //返回字段的默认值
        Map<String,Object> defaultValueMap = new HashMap<>(16);
        List<WfFormColumnEntity> columnEntities = columnManager.getColumnList(masterTableEntity.getId());
        for (WfFormColumnEntity columnEntity : columnEntities) {
            if(StrUtil.isNotBlank(columnEntity.getColumnDefault())){
                defaultValueMap.put(columnEntity.getColumnName(),columnEntity.getColumnDefault());
            }else if(FieldKindConstant.CODE.equals(columnEntity.getFieldKind())){
                //自定义编码
                if(StrUtil.isNotBlank(columnEntity.getDataType())){
                    defaultValueMap.put(columnEntity.getColumnName(),codeRuleHandler.execute(Long.valueOf(columnEntity.getDataType()),null,0));
                }
            }else if(FieldKindConstant.ENVIRONMENT.equals(columnEntity.getFieldKind())){
                //环境变量
                if(StrUtil.isNotBlank(columnEntity.getDataType())){
                    LoginUserVO userVO = LoginUserUtil.getUserInfo().getLoginUserVO();
                    // 将Java对象转换为JSON字符串
                    String jsonString = JSON.toJSONString(userVO);
                    // 将JSON字符串转换为Map
                    JSONObject parsed = JSON.parseObject(jsonString);
                    Map<String, Object> personMap = parsed.getInnerMap();
                    defaultValueMap.put(columnEntity.getColumnName(),personMap.get(columnEntity.getDataType()));
                }
            } else if (FieldKindConstant.NOW_TIME.equals(columnEntity.getFieldKind())) {
                //字段类型 - nowTime
                if(StrUtil.isNotBlank(columnEntity.getDataType())){
                    defaultValueMap.put(columnEntity.getColumnName(),DateUtil.format(LocalDateTime.now(), columnEntity.getDataType()));
                }else{
                    defaultValueMap.put(columnEntity.getColumnName(),LocalDateTime.now());
                }
            } else if (FieldKindConstant.NOW_USER.equals(columnEntity.getFieldKind())) {
                //字段类型 - user
                defaultValueMap.put(columnEntity.getColumnName(),LoginUserUtil.getUserInfo().getLoginUserVO().getId());
            } else if (FieldKindConstant.NOW_ORGANIZATION.equals(columnEntity.getFieldKind())) {
                //字段类型 - organization
                defaultValueMap.put(columnEntity.getColumnName(),LoginUserUtil.getUserInfo().getLoginUserVO().getLoginOrgCode());
            } else if (FieldKindConstant.NOW_POST.equals(columnEntity.getFieldKind())) {
                //字段类型 - post
                defaultValueMap.put(columnEntity.getColumnName(),LoginUserUtil.getUserInfo().getLoginUserVO().getCurPostId());
            } else if (FieldKindConstant.NOW_LEVEL.equals(columnEntity.getFieldKind())) {
                //字段类型 - level
                defaultValueMap.put(columnEntity.getColumnName(),LoginUserUtil.getUserInfo().getLoginUserVO().getLevelId());
            }
        }
        jsonObject.put("defaultValueMap",defaultValueMap);
        return jsonObject;
    }

    /**
     * 根据id获取
     * @param id
     * @return
     */
    @Override
    public WfFormDesignEntity get(Long id) {
        return designManager.getById(id);
    }

    //############################### 私有函数 ###############################

    /**
     * 校验 formDesignCode 是否存在
     */

    private <T extends DesignBaseQuery> void checkFormDesignCode(T query){
        WfFormDesignEntity entity = designManager.getByFormDesignCode(query.getFormDesignCode());
        if(query instanceof DesignInsertQuery && null != entity){
            //表单编码已存在
            Asserts.fail("[wform.formCode.exist]");
        }
        if(query instanceof DesignUpdateQuery && null != entity && !((DesignUpdateQuery) query).getId().equals(entity.getId())){
            //表单编码已存在
            Asserts.fail("[wform.formCode.exist]");
        }
    }
}
